/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.qsdm.es.dao;

import com.qsdm.es.dao.exceptions.IllegalOrphanException;
import com.qsdm.es.dao.exceptions.NonexistentEntityException;
import com.qsdm.es.dao.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import com.qsdm.es.persistence.Profesion;
import com.qsdm.es.persistence.Sectorprofesional;
import com.qsdm.es.persistence.Profesioncompetencia;
import java.util.ArrayList;
import java.util.List;
import com.qsdm.es.persistence.Experiencialaboral;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author alberto
 */
public class ProfesionJpaController extends BasicJpaController {

    public void create(Profesion profesion,boolean openTX) throws PreexistingEntityException, Exception {
        if (profesion.getProfesioncompetenciaList() == null) {
            profesion.setProfesioncompetenciaList(new ArrayList<Profesioncompetencia>());
        }
        if (profesion.getExperiencialaboralList() == null) {
            profesion.setExperiencialaboralList(new ArrayList<Experiencialaboral>());
        }
        if (profesion.getProfesionList() == null) {
            profesion.setProfesionList(new ArrayList<Profesion>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            if(openTX)em.getTransaction().begin();
            Profesion profesionPadre = profesion.getProfesionPadre();
            if (profesionPadre != null) {
                profesionPadre = em.getReference(profesionPadre.getClass(), profesionPadre.getId());
                profesion.setProfesionPadre(profesionPadre);
            }
            Sectorprofesional sectorProfesional = profesion.getSectorProfesional();
            if (sectorProfesional != null) {
                sectorProfesional = em.getReference(sectorProfesional.getClass(), sectorProfesional.getId());
                profesion.setSectorProfesional(sectorProfesional);
            }
            List<Profesioncompetencia> attachedProfesioncompetenciaList = new ArrayList<Profesioncompetencia>();
            for (Profesioncompetencia profesioncompetenciaListProfesioncompetenciaToAttach : profesion.getProfesioncompetenciaList()) {
                profesioncompetenciaListProfesioncompetenciaToAttach = em.getReference(profesioncompetenciaListProfesioncompetenciaToAttach.getClass(), profesioncompetenciaListProfesioncompetenciaToAttach.getProfesioncompetenciaPK());
                attachedProfesioncompetenciaList.add(profesioncompetenciaListProfesioncompetenciaToAttach);
            }
            profesion.setProfesioncompetenciaList(attachedProfesioncompetenciaList);
            List<Experiencialaboral> attachedExperiencialaboralList = new ArrayList<Experiencialaboral>();
            for (Experiencialaboral experiencialaboralListExperiencialaboralToAttach : profesion.getExperiencialaboralList()) {
                experiencialaboralListExperiencialaboralToAttach = em.getReference(experiencialaboralListExperiencialaboralToAttach.getClass(), experiencialaboralListExperiencialaboralToAttach.getId());
                attachedExperiencialaboralList.add(experiencialaboralListExperiencialaboralToAttach);
            }
            profesion.setExperiencialaboralList(attachedExperiencialaboralList);
            List<Profesion> attachedProfesionList = new ArrayList<Profesion>();
            for (Profesion profesionListProfesionToAttach : profesion.getProfesionList()) {
                profesionListProfesionToAttach = em.getReference(profesionListProfesionToAttach.getClass(), profesionListProfesionToAttach.getId());
                attachedProfesionList.add(profesionListProfesionToAttach);
            }
            profesion.setProfesionList(attachedProfesionList);
            em.persist(profesion);
            if (profesionPadre != null) {
                profesionPadre.getProfesionList().add(profesion);
                profesionPadre = em.merge(profesionPadre);
            }
            if (sectorProfesional != null) {
                sectorProfesional.getProfesionList().add(profesion);
                sectorProfesional = em.merge(sectorProfesional);
            }
            for (Profesioncompetencia profesioncompetenciaListProfesioncompetencia : profesion.getProfesioncompetenciaList()) {
                Profesion oldProfesion1OfProfesioncompetenciaListProfesioncompetencia = profesioncompetenciaListProfesioncompetencia.getProfesion1();
                profesioncompetenciaListProfesioncompetencia.setProfesion1(profesion);
                profesioncompetenciaListProfesioncompetencia = em.merge(profesioncompetenciaListProfesioncompetencia);
                if (oldProfesion1OfProfesioncompetenciaListProfesioncompetencia != null) {
                    oldProfesion1OfProfesioncompetenciaListProfesioncompetencia.getProfesioncompetenciaList().remove(profesioncompetenciaListProfesioncompetencia);
                    oldProfesion1OfProfesioncompetenciaListProfesioncompetencia = em.merge(oldProfesion1OfProfesioncompetenciaListProfesioncompetencia);
                }
            }
            for (Experiencialaboral experiencialaboralListExperiencialaboral : profesion.getExperiencialaboralList()) {
                Profesion oldProfesionOfExperiencialaboralListExperiencialaboral = experiencialaboralListExperiencialaboral.getProfesion();
                experiencialaboralListExperiencialaboral.setProfesion(profesion);
                experiencialaboralListExperiencialaboral = em.merge(experiencialaboralListExperiencialaboral);
                if (oldProfesionOfExperiencialaboralListExperiencialaboral != null) {
                    oldProfesionOfExperiencialaboralListExperiencialaboral.getExperiencialaboralList().remove(experiencialaboralListExperiencialaboral);
                    oldProfesionOfExperiencialaboralListExperiencialaboral = em.merge(oldProfesionOfExperiencialaboralListExperiencialaboral);
                }
            }
            for (Profesion profesionListProfesion : profesion.getProfesionList()) {
                Profesion oldProfesionPadreOfProfesionListProfesion = profesionListProfesion.getProfesionPadre();
                profesionListProfesion.setProfesionPadre(profesion);
                profesionListProfesion = em.merge(profesionListProfesion);
                if (oldProfesionPadreOfProfesionListProfesion != null) {
                    oldProfesionPadreOfProfesionListProfesion.getProfesionList().remove(profesionListProfesion);
                    oldProfesionPadreOfProfesionListProfesion = em.merge(oldProfesionPadreOfProfesionListProfesion);
                }
            }
            if(openTX)em.getTransaction().commit();
        } catch (Exception ex) {
            if (findProfesion(profesion.getId()) != null) {
                throw new PreexistingEntityException("Profesion " + profesion + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Profesion profesion) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Profesion persistentProfesion = em.find(Profesion.class, profesion.getId());
            Profesion profesionPadreOld = persistentProfesion.getProfesionPadre();
            Profesion profesionPadreNew = profesion.getProfesionPadre();
            Sectorprofesional sectorProfesionalOld = persistentProfesion.getSectorProfesional();
            Sectorprofesional sectorProfesionalNew = profesion.getSectorProfesional();
            List<Profesioncompetencia> profesioncompetenciaListOld = persistentProfesion.getProfesioncompetenciaList();
            List<Profesioncompetencia> profesioncompetenciaListNew = profesion.getProfesioncompetenciaList();
            List<Experiencialaboral> experiencialaboralListOld = persistentProfesion.getExperiencialaboralList();
            List<Experiencialaboral> experiencialaboralListNew = profesion.getExperiencialaboralList();
            List<Profesion> profesionListOld = persistentProfesion.getProfesionList();
            List<Profesion> profesionListNew = profesion.getProfesionList();
            List<String> illegalOrphanMessages = null;
            for (Profesioncompetencia profesioncompetenciaListOldProfesioncompetencia : profesioncompetenciaListOld) {
                if (!profesioncompetenciaListNew.contains(profesioncompetenciaListOldProfesioncompetencia)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Profesioncompetencia " + profesioncompetenciaListOldProfesioncompetencia + " since its profesion1 field is not nullable.");
                }
            }
            for (Experiencialaboral experiencialaboralListOldExperiencialaboral : experiencialaboralListOld) {
                if (!experiencialaboralListNew.contains(experiencialaboralListOldExperiencialaboral)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Experiencialaboral " + experiencialaboralListOldExperiencialaboral + " since its profesion field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (profesionPadreNew != null) {
                profesionPadreNew = em.getReference(profesionPadreNew.getClass(), profesionPadreNew.getId());
                profesion.setProfesionPadre(profesionPadreNew);
            }
            if (sectorProfesionalNew != null) {
                sectorProfesionalNew = em.getReference(sectorProfesionalNew.getClass(), sectorProfesionalNew.getId());
                profesion.setSectorProfesional(sectorProfesionalNew);
            }
            List<Profesioncompetencia> attachedProfesioncompetenciaListNew = new ArrayList<Profesioncompetencia>();
            for (Profesioncompetencia profesioncompetenciaListNewProfesioncompetenciaToAttach : profesioncompetenciaListNew) {
                profesioncompetenciaListNewProfesioncompetenciaToAttach = em.getReference(profesioncompetenciaListNewProfesioncompetenciaToAttach.getClass(), profesioncompetenciaListNewProfesioncompetenciaToAttach.getProfesioncompetenciaPK());
                attachedProfesioncompetenciaListNew.add(profesioncompetenciaListNewProfesioncompetenciaToAttach);
            }
            profesioncompetenciaListNew = attachedProfesioncompetenciaListNew;
            profesion.setProfesioncompetenciaList(profesioncompetenciaListNew);
            List<Experiencialaboral> attachedExperiencialaboralListNew = new ArrayList<Experiencialaboral>();
            for (Experiencialaboral experiencialaboralListNewExperiencialaboralToAttach : experiencialaboralListNew) {
                experiencialaboralListNewExperiencialaboralToAttach = em.getReference(experiencialaboralListNewExperiencialaboralToAttach.getClass(), experiencialaboralListNewExperiencialaboralToAttach.getId());
                attachedExperiencialaboralListNew.add(experiencialaboralListNewExperiencialaboralToAttach);
            }
            experiencialaboralListNew = attachedExperiencialaboralListNew;
            profesion.setExperiencialaboralList(experiencialaboralListNew);
            List<Profesion> attachedProfesionListNew = new ArrayList<Profesion>();
            for (Profesion profesionListNewProfesionToAttach : profesionListNew) {
                profesionListNewProfesionToAttach = em.getReference(profesionListNewProfesionToAttach.getClass(), profesionListNewProfesionToAttach.getId());
                attachedProfesionListNew.add(profesionListNewProfesionToAttach);
            }
            profesionListNew = attachedProfesionListNew;
            profesion.setProfesionList(profesionListNew);
            profesion = em.merge(profesion);
            if (profesionPadreOld != null && !profesionPadreOld.equals(profesionPadreNew)) {
                profesionPadreOld.getProfesionList().remove(profesion);
                profesionPadreOld = em.merge(profesionPadreOld);
            }
            if (profesionPadreNew != null && !profesionPadreNew.equals(profesionPadreOld)) {
                profesionPadreNew.getProfesionList().add(profesion);
                profesionPadreNew = em.merge(profesionPadreNew);
            }
            if (sectorProfesionalOld != null && !sectorProfesionalOld.equals(sectorProfesionalNew)) {
                sectorProfesionalOld.getProfesionList().remove(profesion);
                sectorProfesionalOld = em.merge(sectorProfesionalOld);
            }
            if (sectorProfesionalNew != null && !sectorProfesionalNew.equals(sectorProfesionalOld)) {
                sectorProfesionalNew.getProfesionList().add(profesion);
                sectorProfesionalNew = em.merge(sectorProfesionalNew);
            }
            for (Profesioncompetencia profesioncompetenciaListNewProfesioncompetencia : profesioncompetenciaListNew) {
                if (!profesioncompetenciaListOld.contains(profesioncompetenciaListNewProfesioncompetencia)) {
                    Profesion oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia = profesioncompetenciaListNewProfesioncompetencia.getProfesion1();
                    profesioncompetenciaListNewProfesioncompetencia.setProfesion1(profesion);
                    profesioncompetenciaListNewProfesioncompetencia = em.merge(profesioncompetenciaListNewProfesioncompetencia);
                    if (oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia != null && !oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia.equals(profesion)) {
                        oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia.getProfesioncompetenciaList().remove(profesioncompetenciaListNewProfesioncompetencia);
                        oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia = em.merge(oldProfesion1OfProfesioncompetenciaListNewProfesioncompetencia);
                    }
                }
            }
            for (Experiencialaboral experiencialaboralListNewExperiencialaboral : experiencialaboralListNew) {
                if (!experiencialaboralListOld.contains(experiencialaboralListNewExperiencialaboral)) {
                    Profesion oldProfesionOfExperiencialaboralListNewExperiencialaboral = experiencialaboralListNewExperiencialaboral.getProfesion();
                    experiencialaboralListNewExperiencialaboral.setProfesion(profesion);
                    experiencialaboralListNewExperiencialaboral = em.merge(experiencialaboralListNewExperiencialaboral);
                    if (oldProfesionOfExperiencialaboralListNewExperiencialaboral != null && !oldProfesionOfExperiencialaboralListNewExperiencialaboral.equals(profesion)) {
                        oldProfesionOfExperiencialaboralListNewExperiencialaboral.getExperiencialaboralList().remove(experiencialaboralListNewExperiencialaboral);
                        oldProfesionOfExperiencialaboralListNewExperiencialaboral = em.merge(oldProfesionOfExperiencialaboralListNewExperiencialaboral);
                    }
                }
            }
            for (Profesion profesionListOldProfesion : profesionListOld) {
                if (!profesionListNew.contains(profesionListOldProfesion)) {
                    profesionListOldProfesion.setProfesionPadre(null);
                    profesionListOldProfesion = em.merge(profesionListOldProfesion);
                }
            }
            for (Profesion profesionListNewProfesion : profesionListNew) {
                if (!profesionListOld.contains(profesionListNewProfesion)) {
                    Profesion oldProfesionPadreOfProfesionListNewProfesion = profesionListNewProfesion.getProfesionPadre();
                    profesionListNewProfesion.setProfesionPadre(profesion);
                    profesionListNewProfesion = em.merge(profesionListNewProfesion);
                    if (oldProfesionPadreOfProfesionListNewProfesion != null && !oldProfesionPadreOfProfesionListNewProfesion.equals(profesion)) {
                        oldProfesionPadreOfProfesionListNewProfesion.getProfesionList().remove(profesionListNewProfesion);
                        oldProfesionPadreOfProfesionListNewProfesion = em.merge(oldProfesionPadreOfProfesionListNewProfesion);
                    }
                }
            }
            
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = profesion.getId();
                if (findProfesion(id) == null) {
                    throw new NonexistentEntityException("The profesion with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            
            Profesion profesion;
            try {
                profesion = em.getReference(Profesion.class, id);
                profesion.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The profesion with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Profesioncompetencia> profesioncompetenciaListOrphanCheck = profesion.getProfesioncompetenciaList();
            for (Profesioncompetencia profesioncompetenciaListOrphanCheckProfesioncompetencia : profesioncompetenciaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Profesion (" + profesion + ") cannot be destroyed since the Profesioncompetencia " + profesioncompetenciaListOrphanCheckProfesioncompetencia + " in its profesioncompetenciaList field has a non-nullable profesion1 field.");
            }
            List<Experiencialaboral> experiencialaboralListOrphanCheck = profesion.getExperiencialaboralList();
            for (Experiencialaboral experiencialaboralListOrphanCheckExperiencialaboral : experiencialaboralListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Profesion (" + profesion + ") cannot be destroyed since the Experiencialaboral " + experiencialaboralListOrphanCheckExperiencialaboral + " in its experiencialaboralList field has a non-nullable profesion field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Profesion profesionPadre = profesion.getProfesionPadre();
            if (profesionPadre != null) {
                profesionPadre.getProfesionList().remove(profesion);
                profesionPadre = em.merge(profesionPadre);
            }
            Sectorprofesional sectorProfesional = profesion.getSectorProfesional();
            if (sectorProfesional != null) {
                sectorProfesional.getProfesionList().remove(profesion);
                sectorProfesional = em.merge(sectorProfesional);
            }
            List<Profesion> profesionList = profesion.getProfesionList();
            for (Profesion profesionListProfesion : profesionList) {
                profesionListProfesion.setProfesionPadre(null);
                profesionListProfesion = em.merge(profesionListProfesion);
            }
            em.remove(profesion);
            
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Profesion> findProfesionEntities() {
        return findProfesionEntities(true, -1, -1);
    }

    public List<Profesion> findProfesionEntities(int maxResults, int firstResult) {
        return findProfesionEntities(false, maxResults, firstResult);
    }

    private List<Profesion> findProfesionEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Profesion.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Profesion findProfesion(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Profesion.class, id);
        } finally {
            em.close();
        }
    }

    public int getProfesionCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Profesion> rt = cq.from(Profesion.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
